package Controller.Game;

import java.awt.Point;
import java.awt.SystemColor;
import java.util.ArrayList;
import java.util.StringTokenizer;

import javax.swing.JPanel;

import com.thoughtworks.xstream.XStream;

import sun.security.krb5.internal.APOptions;
import sun.swing.plaf.synth.Paint9Painter;

import Connection.SendAction;
import Connection.ServerConectionThread;
import Model.Player.Player;
import Model.Universe.Universe;
import Model.Visible.Fleet;
import Model.Visible.Planet;
import Utils.ConstantsImplement;
import Utils.MediaUploder;
import Utils.Timers.Timer;
import Utils.Timers.TimerListener;
import View.Frame.PrincipalFrame;
import View.GUI.FleetGUI;
import View.GUI.PanelWalk;
import View.GUI.PlanetGUI;
import View.Game.GamePanel;

public class GamePanelController implements ConstantsImplement, TimerListener{
	private PrincipalFrame principalFrame_;
	private GamePanel gamePanel_;
	private Universe universe_;
	private PlanetGUI planetGUI[];
	private boolean callToAttack = false;
	private boolean waitToAttack = true;
	private PlanetGUI attaker_;
	private PlanetGUI toAtack_;
	private Player hostPlayer_;
	private Player otherPlayer_;
	private ArrayList<FleetGUI> fleetGUIs;
	private int fleetsize_ = 0;
	private MediaUploder media_;
	private ServerConectionThread server_;
	private SendAction client_;
	private int connectionNumber;
	private Timer timer;
	private ResultPanelController resultpanelcontroller_;

	
	public GamePanelController(MediaUploder media, int race, String oponent_ip) {
		// TODO Auto-generated constructor stub
		connectionNumber = 0;
		if(race == NYAN_RACE){
			media_ = media;
			server_ = new ServerConectionThread(this, CLIENT_PORT);
			universe_ = new Universe(this);
			planetGUI = new PlanetGUI[NUM_PLANETS];
			createThePlanetGUIs();
			fleetGUIs = new ArrayList<FleetGUI>();
			hostPlayer_ = new Player(universe_.getPlanets(0));
			universe_.getPlanets(0).setOwner(hostPlayer_);
			otherPlayer_ = new Player(universe_.getPlanets(1));
			otherPlayer_.setRace(NAYN_RACE);
			universe_.getPlanets(1).setOwner(otherPlayer_);
			timer = new Timer(this, 15);
			gamePanel_ = new GamePanel(this, media);
			server_.start();
			client_ = new SendAction(oponent_ip, SERVER_PORT);
		} else if(race == NAYN_RACE){
			media_ = media;
			universe_ = new Universe(this);
			planetGUI = new PlanetGUI[NUM_PLANETS];
			createThePlanetGUIs();
			fleetGUIs = new ArrayList<FleetGUI>();
			hostPlayer_ = new Player(universe_.getPlanets(1));
			hostPlayer_.setRace(race);
			otherPlayer_ = new Player(universe_.getPlanets(0));
			otherPlayer_.setRace(NYAN_RACE);
			universe_.getPlanets(0).setOwner(otherPlayer_);
			otherPlayer_.setNet_addr(oponent_ip);
			universe_.getPlanets(1).setOwner(hostPlayer_);
			timer = new Timer(this, 15);
			server_ = new ServerConectionThread(this, SERVER_PORT);
			server_.start();
			client_ = new SendAction(oponent_ip, CLIENT_PORT);
			client_.sendPositions(universe_.getPositions());
			gamePanel_ = new GamePanel(this, media);

		}
	}
	
	public void setPrincipalFrame_(PrincipalFrame principalFrame_) {
		this.principalFrame_ = principalFrame_;
	}

	public void setGamePanel_(GamePanel gamePanel_) {
		this.gamePanel_ = gamePanel_;
	}

	public GamePanelController(GamePanel gamePanel, PrincipalFrame principalFrame) {
		// TODO Auto-generated constructor stub
		universe_ = new Universe(this);
		gamePanel_ = gamePanel;
		principalFrame_ = principalFrame;
		createThePlanetGUIs();
	}
	
	public GamePanel getGamePanel_() {
		return gamePanel_;
	}

	public PrincipalFrame getPrincipalFrame_() {
		return principalFrame_;
	}
	
	public int getGamePanelWidth(){
		return gamePanel_.getWidth();
	}
	
	
	public int getGamePanelHeight(){
		return gamePanel_.getHeight();
	}
	
	public void createThePlanetGUIs(){
		for (int i = 0; i < NUM_PLANETS; i++) {
//			System.out.println("Chegou aki!!!");
//			System.out.println(this);
			planetGUI[i] = new PlanetGUI(universe_.getPlanets(i), this);
//			System.out.println("Chegou aki!!!");
		}
	}

	public PlanetGUI[] getPlanetGUI() {
		return planetGUI;
	}

	public void setPlanetGUI(PlanetGUI[] planetGUI) {
		this.planetGUI = planetGUI;
	}
	
	public void update(XStream xStream) {
		
	}
	public void setCallToAttack(boolean callToAttack) {
		this.callToAttack = callToAttack;
	}
	public boolean isCallToAttack() {
		return callToAttack;
	}
	
	public void setToAtack_(PlanetGUI toAtack_) {
		this.toAtack_ = toAtack_;
	}
	
	public PlanetGUI getToAtack_() {
		return toAtack_;
	}
	
	public void setWaitToAttack(boolean waitToAttack) {
		this.waitToAttack = waitToAttack;
	}
	
	public boolean isWaitToAttack() {
		return waitToAttack;
	}
	
	public Universe getUniverse_() {
		return universe_;
	}
	public void setPlayerRace(int race){
		hostPlayer_.setRace(race);
	}
	
	public Player getHostPlayer(){
		return hostPlayer_;
	}
	
//	public void updateFleet(){
//		gamePanel_.repaint();
//	}

	public PlanetGUI getAttaker_() {
		return attaker_;
	}

	public void setAttaker_(PlanetGUI attaker_) {
		this.attaker_ = attaker_;
	}
	
	public ArrayList<FleetGUI> getFleetGUIs() {
		return fleetGUIs;
	}
	
	public void addFleetGUI(FleetGUI fleetGUI){
		fleetGUIs.add(fleetGUI);
		fleetsize_++;
	}
	
	public void removeFleetGUI(FleetGUI fleetGUI){
		fleetGUIs.remove(fleetGUI);
		fleetsize_--;
	}
	
	public int getFleetsize_() {
		return fleetsize_;
	}
	
	public MediaUploder getMedia_() {
		return media_;
	}
	
	public void startGame(){
		principalFrame_.setGamePanelController(this);
		principalFrame_.getContentPane().removeAll();
		principalFrame_.addContentPane(this.getGamePanel_());
		principalFrame_.repaint();
		principalFrame_.setVisible(true);
		timer.start();
		universe_.startPlanetTimer();
	}
	
	public void setPlanetsPosition(Point[] positions){
		for (int i = 0; i < NUM_PLANETS; i++) {
			universe_.getPlanets(i).setPosition_(positions[i]);
		}
	}
	
	public void cmdParse(String xml) {
		// TODO Auto-generated method stub
		XStream xStream = new XStream();
		//System.out.println("TOCHAMANDO A FUNCAO");
		if(connectionNumber == 0 && hostPlayer_.getRace_() == NYAN_RACE){
			setPlanetsPosition((Point[]) (xStream.fromXML(xml)));
			startGame();
			client_.sendMessage("START");
			connectionNumber++;
		}else{
			String cmd = (String) xStream.fromXML(xml);
			//System.out.println("aki2:"+cmd);
			StringTokenizer parse = new StringTokenizer(cmd);
			cmd = parse.nextToken();
			if(cmd.equals("START")){
				startGame();
			}if(cmd.equals("ATK")){
				String planet_atk = parse.nextToken();
				String planet_def = parse.nextToken();
				String numships = parse.nextToken();
				
				universe_.getPlanets(planet_atk).attackPlanet(universe_.getPlanets(planet_def), Integer.parseInt(numships));
				
			}if(cmd.equals("CREATEI")){
				String planet = parse.nextToken();
//				System.out.println(planet);
//				System.out.println(universe_.getPlanets(planet));
				universe_.getPlanets(planet).NETcreateIndustry();
				
			}if(cmd.equals("CREATEFM")){
				String planet = parse.nextToken();
				
				universe_.getPlanets(planet).NETcreateFleetMaker();
				
			}if(cmd.equals("CREATEF")){
				String planet = parse.nextToken();
				String numships = parse.nextToken();
				
				universe_.getPlanets(planet).setShipsToCreate_(Integer.parseInt(numships));
				universe_.getPlanets(planet).NETcreateFleet();
				
			}if(cmd.equals("CREATED")){
				String planet = parse.nextToken();
				
				universe_.getPlanets(planet).NETcreateDefences();
				
			}if(cmd.equals("UPDATEI")){
				String planet = parse.nextToken();
				
				universe_.getPlanets(planet).NETupdateIndustry();
				
			}if(cmd.equals("UPDATEFM")){
				String planet = parse.nextToken();
				
				universe_.getPlanets(planet).NETupdateFleetMaker();
				
			}if(cmd.equals("UPDATED")){
				String planet = parse.nextToken();
				
				universe_.getPlanets(planet).NETupdateDefenses();
				
			}if(cmd.equals("FINISH")){
				
			}
		}
		
	}
	
//	 public static void main(String[] args) {
//		GamePanelController  gamePanelController = null;
//		gamePanelController = new GamePanelController(new MediaUploder(), NAYN_RACE, "127.0.0.1");
//		XStream xStream = new XStream();
//		String xml = new String();
//		xml = xStream.toXML(gamePanelController.getUniverse_().getPositions());
//		System.out.println(xml);
//	}
	 
	 public SendAction getClient_() {
		return client_;
	}
	 
	 @Override
	public void update() {
		// TODO Auto-generated method stub		 
		gamePanel_.repaint();
		
		if(hostPlayer_.getNumPlanets() == 20 || otherPlayer_.getNumPlanets() == 0){
			System.out.println("vc ganhou");
			universe_.stopPlanetTimer();
			timer.setRun_(false);
			gamePanel_.setVisible(false);
			resultpanelcontroller_= new ResultPanelController(true, media_, principalFrame_);
		}else if(hostPlayer_.getNumPlanets() == 0 || otherPlayer_.getNumPlanets() == 20){
			System.out.println("vc perdeu");
			universe_.stopPlanetTimer();
			timer.setRun_(false);
			gamePanel_.setVisible(false);
			resultpanelcontroller_= new ResultPanelController(false, media_, principalFrame_);
		}
	}
	
}
